package components
{
	import mx.charts.AxisRenderer;
	import mx.charts.CategoryAxis;
	import mx.charts.ColumnChart;
	import mx.charts.GridLines;
	import mx.charts.HitData;
	import mx.charts.LinearAxis;
	import mx.charts.chartClasses.Series;
	import mx.charts.events.ChartItemEvent;
	import mx.charts.series.*;
	import mx.collections.ArrayCollection;
	import mx.controls.Label;
	import mx.graphics.SolidColor;
	import mx.graphics.Stroke;
	
	import org.quantitativesustainability.styles.Styles;

	public class QSChart extends ColumnChart implements QSChartInterface
	{
		internal var styles:Styles=new Styles();
		private var _genInfo:String;
		private var _discussion:String;

		public var costLabel:Label;

		public function set genInfo(s:String):void
		{
			_genInfo=s;
		}

		public function get genInfo():String
		{
			return _genInfo;
		}

		public function set discussion(s:String):void
		{
			_discussion=s;
		}

		public function get discussion():String
		{
			return _discussion;
		}

		// AXES AND SERIES:
		// ... horizontal axis:
		public var hax:CategoryAxis=new CategoryAxis();

		// ... vertical series, their axes, and renderers:
		public var sTotalCost:ColumnSeries=new ColumnSeries();

		public var sCol:ColumnSeries=new ColumnSeries();
		public var vaxCol:LinearAxis=new LinearAxis();
		public var vaxRnCol:AxisRenderer=new AxisRenderer();

		public var sEF:PlotSeries=new PlotSeries();
		public var vaxEF:LinearAxis=new LinearAxis();
		public var vaxRnEF:AxisRenderer=new AxisRenderer();

		public var sGen:PlotSeries=new PlotSeries();
		public var vaxGen:LinearAxis=new LinearAxis();
		public var vaxRnGen:AxisRenderer=new AxisRenderer();

		public function QSChart()
		{
			super();
		}

		public function init(dpp:ArrayCollection):void
		{
			this.dataProvider=dpp;

			// DATA-TIPS:
			this.dataTipFunction=_dataTipFunction;
			this.showDataTips=true;
			this.dataTipMode='single';
			//this.itemClick="displayInfo(event)";

			// HORIZONTAL AXIS:
			hax.dataProvider=this.dataProvider;
			hax.categoryField='label';
			hax.title='';
			this.horizontalAxis=hax;

			render();
			addSeries(); // Also set visibility of series and axes;
		}

		public function addSeries():void
		{
			// ADD SERIES:
			// ... cost:
			sCol.dataProvider=this.dataProvider;
			sCol.id='sCol';
			sCol.xField='label';
			sCol.yField='cost';
			sCol.displayName='sCol';
			sCol.setStyle('fill', null);
			sCol.setStyle('stroke', new Stroke(styles.c_sb2_4));
			vaxCol.title="Total cost  [ c$ / kWh ]";
			vaxCol.minimum=0;
			sCol.verticalAxis=vaxCol;

			// ... totalCost:
			sTotalCost.dataProvider=this.dataProvider;
			sTotalCost.xField='label';
			sTotalCost.yField='totalCost';
			sTotalCost.minField='cost';
			sTotalCost.displayName='sTotalCost';
			sTotalCost.setStyle('fill', new SolidColor(styles.c_sb2_3, 1));
			sTotalCost.setStyle('stroke', new Stroke(styles.c_sb2_3));

			// ... emissionFactor
			sEF.dataProvider=this.dataProvider;
			sEF.xField='label';
			sEF.yField='emissionFactor';
			sEF.setStyle('stroke', null);
			sEF.displayName='sGen';
			sEF.setStyle('fill', new SolidColor(styles.c_sg0_0, 1));
			vaxEF.title="Emission factor  [ kg CO2 / kWh ]";
			vaxEF.minimum=0;
			sEF.verticalAxis=vaxEF;
			sEF.visible=false;
			vaxRnEF.visible=false;

			// ... generation 
			sGen.dataProvider=this.dataProvider;
			sGen.xField='label';
			sGen.yField='generation';
			sGen.setStyle('stroke', null);
			sGen.displayName='sGen';
			sGen.setStyle('fill', new SolidColor(styles.c_sg0_1, 1));
			vaxGen.title="Generation  [ TWh / day ]";
			vaxGen.minimum=0;
			sGen.verticalAxis=vaxGen;
			sGen.visible=false;
			vaxRnGen.visible=false;

			// ... add to graph:
			var series:Array=new Array();
			series.push(sCol);
			series.push(sTotalCost);
			series.push(sEF);
			series.push(sGen);
			this.series=series;

		}

		public function render():void
		{
			// Get rid of shadows:
			this.seriesFilters=[];

			this.type='overlaid';

			var gl:GridLines=new GridLines();
			gl.y=0;
			gl.setStyle('direction', 'horizontal')
			gl.setStyle('verticalShowOrigin', false);
			gl.setStyle('horizontalStroke', styles.st_gridlines);
			gl.setStyle('horizontalOriginStroke', styles.st_origin);
			var bge:Array=new Array();
			bge.push(gl);
			this.backgroundElements=bge;

			var ar:AxisRenderer=new AxisRenderer();
			ar.axis=hax;
			ar.placement='bottom';
			ar.setStyle('axisStroke', styles.st_axis);
			ar.setStyle('tickPlacement', 'none');
			// BODGE: This is deprecated, but adding to 'horizontalAxisRenderers' adds an 
			// axis rather than modifying the existing one. 
			this.horizontalAxisRenderer=ar;
			//this.horizontalAxisRenderers = har;

			var vaxrs:Array=new Array();

			vaxRnCol.axis=vaxCol;
			vaxRnCol.placement='left';
			vaxRnCol.setStyle('axisStroke', new Stroke(styles.c_sb2_4, 1));
			vaxRnCol.setStyle('tickPlacement', 'none');
			vaxRnCol.setStyle('verticalAxisTitleAlignment', 'vertical');
			vaxRnCol.setStyle('labelGap', 8);
			vaxRnCol.setStyle('color', styles.c_sb2_4);
			vaxrs.push(vaxRnCol);

			vaxRnEF.axis=vaxEF;
			vaxRnEF.placement='right';
			vaxRnEF.setStyle('axisStroke', new Stroke(styles.c_sg0_2, 1));
			vaxRnEF.setStyle('tickPlacement', 'none');
			vaxRnEF.setStyle('verticalAxisTitleAlignment', 'vertical');
			vaxRnEF.setStyle('labelGap', 8);
			vaxRnEF.setStyle('color', styles.c_sg0_2);
			vaxrs.push(vaxRnEF);

			vaxRnGen.axis=vaxGen;
			vaxRnGen.placement='right';
			vaxRnGen.setStyle('axisStroke', new Stroke(styles.c_sg0_1, 1));
			vaxRnGen.setStyle('tickPlacement', 'none');
			vaxRnGen.setStyle('verticalAxisTitleAlignment', 'vertical');
			vaxRnGen.setStyle('labelGap', 8);
			vaxRnGen.setStyle('color', styles.c_sg0_1);
			vaxrs.push(vaxRnGen);

			// BODGE: Gotta set the following to get rid of the default axis....?
			this.verticalAxisRenderer=vaxrs[0];
			this.verticalAxisRenderers=vaxrs;
		}

		public function updateCarbonPrice(value:Number):void
		{
			var totalCost:Number = 0;
			// BODGE.  Sum this somewhere (sumwhere) else, not here. 
			var totalGen:Number = 0;
			for (var i:Object in dataProvider)
			{
				dataProvider[i].totalCost=
					// c$
					dataProvider[i].cost
					// [kg / kWh] * [$ / ton] * {100 [c$ / $] * 1e-3 [ton / kg]}  
					+ dataProvider[i].emissionFactor * value * 0.1;
				totalCost += dataProvider[i].totalCost * dataProvider[i].generation;
				totalGen += dataProvider[i].generation;
			}
			costLabel.text=String((totalCost / totalGen).toPrecision(2)) + ' c$ / kWh';
			
		}

		public function showSeries(a:AxisRenderer, s:Series):void
		{
			if (a.visible == true || s.visible == true)
			{
				a.visible=false;
				s.visible=false;
			}
			else
			{
				a.visible=true;
				s.visible=true;
			}
		}

		private function _dataTipFunction(hd:HitData):String
		{
			if (hd.element == sCol || hd.element == sTotalCost)
			{
				var rtVal:String='<b>Cost  [ &#162; / kWh ]</b><br>------------------------\n';
				rtVal+="Raw cost = <i>" + hd.item.cost.toPrecision(2) + '</i>\n';
				rtVal+="Carbon cost = <i>" +
					(hd.item.totalCost - hd.item.cost).toPrecision(2).toString() +
					'</i>\n';
				rtVal+='<b>Total cost</b> = <i>' + hd.item.totalCost.toPrecision(2) +
					'</i>\n';
				return rtVal;
			}
			else if (hd.element == sEF)
			{
				rtVal='<b>Emission factor</b> = ' + String(hd.item.emissionFactor.toPrecision(3));
				rtVal+=' [ kg CO2 / kWh ]';
				return rtVal;
			}
			else if (hd.element == sGen)
			{
				rtVal='<b>Generation quantity</b> = ' + String(hd.item.generation.toPrecision(3));
				rtVal+=' [ TWh / day ]';
				return rtVal;
			}
			return '';
		}

		public function getChartItemInfo(e:ChartItemEvent):String
		{
			var rtVal:String='<i>No further information.</i>';
			if (e.hitData.item.info is String)
				rtVal=(e.hitData.item.info);
			return rtVal;
		}
	} //Class.
}